package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

// 编写一个Go程序，该程序接受一个整数n作为输入，并启动n个goroutine。
// 每个goroutine应计算从1到100的整数之和，并将结果打印到控制台。
// 所有goroutine都完成后，主程序应输出所有goroutine计算的总和。
//
// 提示：
// 使用sync.WaitGroup来等待所有goroutine完成。
// 使用通道（channel）来收集每个goroutine的计算结果。
// 确保在所有goroutine完成计算后关闭通道。
// 在主函数中，从通道中读取每个goroutine的结果，并计算总和。

func main() {
	//calc(10000)
	//cCh := make(chan int)
	//go producer(cCh)
	//go consumer(cCh)
	//time.Sleep(time.Second * 30)
	demo2()
}

func calc(n int) {
	resCh := make(chan int, n)
	var res int

	for i := 0; i < n; i++ {
		go calc2(resCh)
	}

	// 等待所有的 goroutine 完成并关闭通道
	//for v := range resCh {
	//	fmt.Println(v)
	//}
	// 保证所有 goroutine 都完成后关闭通道
	for i := 1; i <= n; i++ {
		res += <-resCh
	}

	// 关闭通道
	close(resCh)

	fmt.Println(res)
}

func calc2(rCh chan int) {
	rCh <- 5050
}

// 题目：
//
// 设计一个程序模拟一个简单的生产者-消费者模型。生产者每隔一段时间生成一个随机数并发送到通道中，
// 消费者从通道中读取数据并打印。确保生产者和消费者在不同的goroutine中运行，并且通道的缓冲区大小为5。
//
// 要求：
//
// 生产者每秒钟生成一个随机数（可以使用 rand.Intn() 函数生成范围在1到100之间的随机数）并发送到通道中。
// 消费者每秒钟从通道中读取一个随机数并打印出来。
// 程序运行一段时间后结束，例如运行30秒。
// 请写出完整的Go语言代码实现这个模拟生产者-消费者模型的程序。

func producer(pCh chan<- int) {
	for {
		rand.New(rand.NewSource(time.Now().Unix()))
		randNum := rand.Intn(100) + 1
		pCh <- randNum
		//time.Sleep(time.Second)
	}
}

func consumer(cCh <-chan int) {
	for {
		fmt.Println(<-cCh)
		//time.Sleep(time.Second)
	}
}

// demo1 通道误用导致的bug
// demo1 通道误用导致的bug
func demo1() {
	wg := sync.WaitGroup{}

	ch := make(chan int, 10)
	for i := 0; i < 10; i++ {
		ch <- i
	}
	close(ch)

	wg.Add(3)
	for j := 0; j < 3; j++ {
		go func() {
			for v := range ch {
				fmt.Println(v)
			}
			wg.Done()
		}()
	}
	wg.Wait()
}

// demo2 通道误用导致的bug
func demo2() {
	ch := make(chan string)
	go func() {
		// 这里假设执行一些耗时的操作
		time.Sleep(3 * time.Second)
		ch <- "job result"
	}()

	select {
	case result := <-ch:
		fmt.Println(result)
	case <-time.After(time.Second): // 较小的超时时间
		return
	}
}
